from flask import Flask, request, jsonify
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
import mysql.connector
from mysql.connector import Error
from flask_cors import CORS
from datetime import datetime
app = Flask(__name__)
app.json_provider_class.ensure_ascii = False
CORS(app)  # 允许跨域请求

# ...
#app = Flask(__name__)
# MongoDB 连接
try:
    # 修改为你的阿里云服务器公网 IP
    username = "iot_admin"
    password = "Ylt20250015"
    mongo_client = MongoClient(f'mongodb://{username}:{password}@8.137.20.120:27017/',serverSelectionTimeoutMS=5000)
    mongo_client.admin.command('ping')
    mongo_db = mongo_client['iot_data_db']
    mongo_collection = mongo_db['device_records']
except Exception as e:
    print(f"MongoDB 连接失败: {e}")

# MySQL 连接
# MySQL 连接
try:
    # 修改为你的阿里云服务器公网 IP 和 MySQL 用户信息
    mysql_connection = mysql.connector.connect(
        host='8.137.20.120',
        port=3306,
        database='iot_data',
        user='root',
        password='liuzheyu2268'
    )
    if mysql_connection.is_connected():
        mysql_cursor = mysql_connection.cursor()
        
        # 初始化数据库表
        # 创建user表
        create_user_table = """
        CREATE TABLE IF NOT EXISTS user (
            id INT AUTO_INCREMENT PRIMARY KEY,
            username VARCHAR(50) UNIQUE NOT NULL,
            password VARCHAR(100) NOT NULL,
            created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        )
        """
        mysql_cursor.execute(create_user_table)
        
        # 确保device_status表也存在
        create_device_status_table = """
        CREATE TABLE IF NOT EXISTS device_status (
            id INT AUTO_INCREMENT PRIMARY KEY,
            device_id VARCHAR(50) UNIQUE NOT NULL,
            enabled BOOLEAN NOT NULL,
            mode VARCHAR(20) NOT NULL,
            updated_at TIMESTAMP NOT NULL
        )
        """
        mysql_cursor.execute(create_device_status_table)
        
        mysql_connection.commit()
        print("数据库表初始化完成")
        
except Error as e:
    print(f"Error while connecting to MySQL: {e}")

# ------------------- 接口1：设备数据上传接口 -------------------
@app.route('/api/data/upload', methods=['POST'])
def upload_data():
    try:
        data = request.json
        required_params = ['record_time', 'device_id', 'heart_rate', 'stride_length',
                          'stride_frequency', 'temperature', 'connection_status', 'enabled', 'mode']
        missing = [p for p in required_params if p not in data]
        if missing:
            return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

        # 添加接收时间戳
        data["received_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        try:
            # 完整存储所有数据到MongoDB
            mongo_collection.insert_one(data)
            print("成功保存到MongoDB")
        except Exception as e:
            print(f"MongoDB 保存失败: {e}")
            return jsonify({'status': 'error', 'message': '数据保存失败'}), 500
        
        try:
            # 只存储enabled和mode到MySQL
            query = """
            INSERT INTO device_status (device_id, enabled, mode, updated_at)
            VALUES (%s, %s, %s, %s)
            ON DUPLICATE KEY UPDATE 
                enabled = VALUES(enabled),
                mode = VALUES(mode),
                updated_at = VALUES(updated_at)
            """
            values = (
                data['device_id'],
                data['enabled'],
                data['mode'],
                data['record_time']
            )
            
            # 确保MySQL连接有效
            if not mysql_connection.is_connected():
                mysql_connection.reconnect()
            
            mysql_cursor.execute(query, values)
            mysql_connection.commit()
            print("成功保存设备状态到MySQL")
        except Error as e:
            print(f"MySQL 保存状态失败: {e}")
            # 不返回错误，因为主数据已存到MongoDB

        return jsonify({'status': 'success', 'message': 'Data uploaded successfully'}), 200
        
    except Exception as e:
        print(f"处理请求时出现异常: {e}")
        return jsonify({'status': 'error', 'message': '服务器内部错误'}), 500
        

        
    
# ------------------- 接口2：用户注册接口 -------------------
@app.route('/api/user/register', methods=['POST'])
def user_register():
    data = request.json
    required_params = ['username', 'password']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'缺少参数: {missing}'}), 400

    try:
        # 检查用户名是否已存在
        check_query = "SELECT id FROM user WHERE username = %s"
        mysql_cursor.execute(check_query, (data['username'],))
        if mysql_cursor.fetchone():
            return jsonify({'status': 'error', 'message': '用户名已存在'}), 400

        # 插入新用户
        insert_query = """
        INSERT INTO user (username, password) 
        VALUES (%s, %s)
        """
        values = (data['username'], data['password'])
        mysql_cursor.execute(insert_query, values)
        mysql_connection.commit()
        return jsonify({'status': 'success', 'message': '注册成功'}), 200

    except Error as e:
        print(f"注册失败: {e}")
        return jsonify({'status': 'error', 'message': '数据库错误'}), 500
# ------------------- 接口3：设备注册接口 -------------------
@app.route('/api/device/register', methods=['POST'])
def device_register():
    data = request.json
    required_params = ['device_id', 'device_type', 'firmware_version']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

    # 模拟设备注册处理
    print("Registering device:", data)
    return jsonify({'status': 'success', 'message': 'Device registered successfully'}), 200
# ------------------- 接口4：设备心跳/自检接口 -------------------
@app.route('/api/device/heartbeat', methods=['POST'])
def device_heartbeat():
    data = request.json
    required_params = ['device_id', 'battery_level', 'firmware_version', 'status']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

    # 模拟处理心跳信息
    print("Heartbeat from device:", data)
    return jsonify({'status': 'success', 'message': 'Heartbeat received'}), 200

# ------------------- 接口5：设备固件更新检查接口 -------------------
@app.route('/api/device/firmware/check', methods=['POST'])
def firmware_check():
    data = request.json
    required_params = ['device_id', 'current_firmware']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

    latest_firmware = "1.1.0"
    if data['current_firmware'] != latest_firmware:
        return jsonify({
            'status': 'success', 
            'message': 'Update available', 
            'latest_firmware': latest_firmware
        }), 200
    else:
        return jsonify({'status': 'success', 'message': 'Device is up-to-date'}), 200

# ------------------- 接口6：用户登录接口 -------------------
@app.route('/api/user/login', methods=['POST'])
def user_login():
    data = request.json
    required_params = ['username', 'password']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'缺少参数: {missing}'}), 400

    try:
        # 查询用户信息
        query = "SELECT password FROM user WHERE username = %s"
        mysql_cursor.execute(query, (data['username'],))
        result = mysql_cursor.fetchone()
        
        if not result:
            return jsonify({'status': 'error', 'message': '用户不存在'}), 401
            
        # 对比明文密码
        if data['password'] != result[0]:
            return jsonify({'status': 'error', 'message': '密码错误'}), 401
            
        return jsonify({'status': 'success', 'message': '登录成功'}), 200

    except Error as e:
        print(f"登录失败: {e}")
        return jsonify({'status': 'error', 'message': '系统错误'}), 500
    # ------------------- 接口7：用户信息查询接口 -------------------
@app.route('/api/user/info', methods=['GET'])
def user_info():
    # 获取查询参数，假设使用 token 作为身份验证依据
    token = request.args.get('token')
    if not token:
        return jsonify({'status': 'error', 'message': 'Missing token parameter'}), 400

    # 模拟查询用户信息
    user_info = {
        'username': 'testuser',
        'email': 'test@example.com',
        'registered_at': '2025-01-01'
    }
    return jsonify({'status': 'success', 'data': user_info}), 200
# ------------------- 接口8：设备数据查询接口 -------------------
@app.route('/api/data/query', methods=['POST'])
def data_query():
    try:
        data = request.json
        required_params = ['device_id', 'start_time', 'end_time']
        missing = [p for p in required_params if p not in data]
        if missing:
            return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

        # 统一日期时间格式
        start_time = data['start_time']
        if len(start_time) == 10:  # "YYYY-MM-DD"
            start_time += " 00:00:00"
        
        end_time = data['end_time']
        if len(end_time) == 10:    # "YYYY-MM-DD"
            end_time += " 23:59:59"
        
        # 从MongoDB查询完整数据
        try:
            # 构建查询条件
            query = {
                "device_id": data['device_id'],
                "record_time": {
                    "$gte": start_time,
                    "$lte": end_time
                }
            }
            
            # 执行查询
            results = mongo_collection.find(query).sort("record_time", -1)
            
            # 转换为可序列化格式
            records = []
            for doc in results:
                # 移除MongoDB的_id字段
                doc.pop('_id', None)
                records.append(doc)
                
            return jsonify({'status': 'success', 'data': records}), 200
            
        except Exception as e:
            print(f"MongoDB查询失败: {e}")
            return jsonify({'status': 'error', 'message': '数据查询失败'}), 500
            
    except Exception as e:
        print(f"处理请求时出现异常: {e}")
        return jsonify({'status': 'error', 'message': '服务器内部错误'}), 500
    
# ------------------- 接口新：设备接口 -------------------
@app.route('/api/device/status', methods=['GET'])  
def device_status():
    device_id = request.args.get('device_id')
    if not device_id:
        return jsonify({'status': 'error', 'message': '缺少device_id参数'}), 400

    try:
        # 从MySQL获取设备最新状态
        query = """
        SELECT enabled, mode, updated_at 
        FROM device_status 
        WHERE device_id = %s
        ORDER BY updated_at DESC 
        LIMIT 1
        """
        
        # 确保MySQL连接有效
        if not mysql_connection.is_connected():
            mysql_connection.reconnect()
        
        mysql_cursor.execute(query, (device_id,))
        result = mysql_cursor.fetchone()
        
        if result:
            status_info = {
                "device_id": device_id,
                "enabled": result[0],
                "mode": result[1],
                "last_updated": result[2].strftime("%Y-%m-%d %H:%M:%S")
            }
            return jsonify({'status': 'success', 'data': status_info}), 200
        else:
            return jsonify({'status': 'error', 'message': '未找到设备状态信息'}), 404
            
    except Error as e:
        print(f"MySQL查询设备状态失败: {e}")
        return jsonify({'status': 'error', 'message': '数据库错误'}), 500
# ------------------- 接口9：设备状态监控接口 -------------------
@app.route('/api/device/status/invalid', methods=['GET'])
def device_status_invalid():
    """
    返回设备的状态信息。

    Args:
        无

    Returns:
        dict: 包含设备状态信息的JSON字典。

    Raises:
        HTTPException: 如果请求中缺少device_id参数，则抛出HTTP 400异常。

    """
    device_id = request.args.get('device_id')
    if not device_id:
        return jsonify({'status': 'error', 'message': 'Missing device_id parameter'}), 400

    # 模拟返回设备最新状态
    status_info = {
        "device_id": device_id,
        "last_active": "2025-03-17 10:05:00",
        "connection_status": True,
        "battery_level": 85
    }
    return jsonify({'status': 'success', 'data': status_info}), 200

# ------------------- 接口10：设备报警接口 -------------------
@app.route('/api/device/alert', methods=['POST'])
def device_alert():
    data = request.json
    required_params = ['device_id', 'alert_type', 'alert_message', 'timestamp']
    missing = [p for p in required_params if p not in data]
    if missing:
        return jsonify({'status': 'error', 'message': f'Missing parameters: {missing}'}), 400

    # 模拟处理报警（记录报警日志、通知相关人员等）
    print("Device alert:", data)
    return jsonify({'status': 'success', 'message': 'Alert received'}), 200

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=5000, threaded=True)
